package com.users.rn.common.download.impl

import android.content.Context
import android.text.TextUtils
import com.users.rn.common.network.utils.FileUtil
import com.users.rn.common.plugin.PluginHelper
import com.users.rn.common.plugin.RNPluginFieldKey
import com.liulishuo.filedownloader.model.FileDownloadStatus
import com.users.rn.rncommon.download.ALHPluginDownloadService
import com.users.rn.rncommon.network.utils.SharePreferenceUtils
import com.users.rn.rncommon.plugin.PluginInformation
import com.users.rn.rncommon.util.EncryptUtils
import com.users.rn.rncommon.util.RNLogger
import com.users.rn.rncommon.util.ZipFileUtil
import java.io.File

/**

 * 作者：wolf on 1/11/21 15:15

 * 邮箱：bluce

 */

object ZipUtils {
    const val TAG = "RN_COMMON_PLUGIN"

    /**
     * 解压与保存文件
     */
    fun unzipPlugin(context: Context, pluginInfor: PluginInformation, listener: ALHPluginDownloadService.PluginDownloadListener?) {
        //下载成功MD5校验,保存数据
        val file = File(pluginInfor.fullFilePath)
        if (!file.exists()) {
            //指定文件不存在
            RNLogger.e(TAG, "file not exiting")
            listener?.onComputerTask(pluginInfor.pluginName, -1, false, FileDownloadStatus.error)
        } else if (fileMd5Check(pluginInfor.fullFilePath, pluginInfor.md5)) {
            upzipTask(context, pluginInfor, listener)
        } else {
            RNLogger.e(TAG, "文件校验失败")
            listener?.onComputerTask(pluginInfor.pluginName, -1, false, FileDownloadStatus.error)
        }
    }

    fun unzipBundle(context: Context, pluginName: String): Boolean {
        val sharePreference = SharePreferenceUtils.getPreference(context, pluginName)
        val fullPath = sharePreference.getString(RNPluginFieldKey.FILE_FULL_PATH, "")
        val filePath = sharePreference.getString(RNPluginFieldKey.FILE_PATH, "")
        if (fullPath.isNullOrEmpty() || filePath.isNullOrEmpty()) {
            return false
        }
        try {
            val file = File(fullPath)
            if (file.exists()) {
                ZipFileUtil.unzipFile(file, filePath, null)
                return true
            }
        } catch (err: Exception) {
            err.printStackTrace()
            return false
        }
        return false
    }

    private fun upzipTask(context: Context, pluginInformation: PluginInformation, listener: ALHPluginDownloadService.PluginDownloadListener?) {
        ZipFileUtil.unzipFile(File(pluginInformation.fullFilePath), pluginInformation.filePath) { status, _ ->
            if (status == ZipFileUtil.UnZipProgress.STATUS_COMPLETE) {
                checkPluginIsMove(pluginInformation)
                PluginHelper.savePluginInfo(context, pluginInformation)
                listener?.onComputerTask(pluginInformation.pluginName, 0, true, FileDownloadStatus.completed)
                deleteOldPluginFile(pluginInformation.pluginName, pluginInformation.pluginVersion.toString())
            } else if (status == ZipFileUtil.UnZipProgress.STATUS_FAILURE) {
                deleteTempFile(pluginInformation.filePath, pluginInformation.url)
                listener?.onComputerTask(pluginInformation.pluginName, -1, false, FileDownloadStatus.error)
            }
        }
    }

    /**
     * 判断是否移动路径
     */
    private fun checkPluginIsMove(pluginInformation: PluginInformation) {
        //移动路径
        var fileName = File(pluginInformation.fullFilePath).name
        if (fileName.indexOf(".") >= 0) {
            fileName = fileName.substring(0, fileName.indexOf("."))
        }
        val tempFile = File(pluginInformation.filePath, fileName)
        if (tempFile.exists() && tempFile.exists()) {
            FileUtil.moveFilesTo(tempFile, File(pluginInformation.filePath))
            FileUtil.delDir(tempFile)
        }
    }

    /**
     * 删除老版本
     */
    private fun deleteOldPluginFile(pluginName: String, pluginVersion: String) {
        var fileDir = PluginInformation.getBasicDir() + File.separator + pluginName
        val file = File(fileDir)
        if (file.exists() && file.isDirectory) {
            file.listFiles().forEach {
                if (it.name != pluginVersion) {
                    FileUtil.delFolder(it.absolutePath)
                }
            }
        }
    }

    private fun deleteTempFile(filePath: String, fileName: String) {
        FileUtil.delFile(filePath + fileName)
        var preFileName = fileName
        if (fileName != null) {
            preFileName = filePath.substring(0, filePath.lastIndexOf('/'))
        }
        FileUtil.delFile(preFileName)
        FileUtil.delFolder(filePath)
    }


    /**
     * 文件md5值校验
     *
     * @param filePath 文件路径
     * @param md5      MD5值
     * @return 校验通过返回true否则返回false
     */
    private fun fileMd5Check(filePath: String, md5: String): Boolean {
        val file = File(filePath)
        if (TextUtils.isEmpty(md5) || TextUtils.isEmpty(filePath) || !file.exists()) { //指定文件不存在
            RNLogger.e(TAG, "file not exiting")
            return false
        }
        val localFileMd5 = EncryptUtils.fileMD5(file.absolutePath) //本地文件md5值
        if (TextUtils.isEmpty(localFileMd5)) {
            return false
        }
        val targetFileMd5 = if (TextUtils.isEmpty(md5)) null else md5.toLowerCase()
        return localFileMd5 == targetFileMd5
    }
}